package ro.one.gaeql;
import java.io.IOException;
import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;

import ro.one.gaeql.common.QueryManager;
import ro.one.gaeql.common.UpdateExecutor;
import ro.one.gaeql.model.UpdateQuery;
import ro.one.gaeql.parser.UpdateQueryLexer;
import ro.one.gaeql.parser.UpdateQueryParser;

@SuppressWarnings("serial")
public class QlServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {        
        String queryParameter = req.getParameter("query");
        String stopParameter = req.getParameter("stopIdJob");
        String jobStatusParameter = req.getParameter("jobStatus");
        String createTestData = req.getParameter("createTestData");
        
        if (queryParameter != null) {
        	doQuery(req, resp, queryParameter);
        }
        else if (stopParameter != null) {
        	doStop(req, resp, stopParameter);
        }
        else if (jobStatusParameter != null) {
        	doGetJobStatus(req, resp, jobStatusParameter);
        }
        else if (createTestData != null) {
        	doTestData(req, resp);
        }
        else {
        	doGetJobs(req, resp);
        }
	}

	private void doGetJobStatus(HttpServletRequest req, HttpServletResponse resp, String idJob) throws IOException {
		QueryManager queryManager = new QueryManagerFactory().createQueryManager();
		
		resp.setContentType("text/plain");
		resp.getWriter().println(queryManager.getJobOutput(idJob));
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doGet(req, resp);
	}
	
	private void doTestData(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		QueryManager queryManager = new QueryManagerFactory().createQueryManager();
		queryManager.createTestData();
		
		resp.setContentType("text/plain");
		resp.getWriter().println("done.");
	}

	private void doGetJobs(HttpServletRequest req, HttpServletResponse resp) throws IOException { 
		QueryManager queryManager = new QueryManagerFactory().createQueryManager();
		StringBuilder sb = new StringBuilder();
		
		Iterator<String> jobs = queryManager.getJobs();
		
		sb.append("{\"idJob\":[");
		while(jobs.hasNext()) {
			sb.append(" \"" + jobs.next() + "\",");
		}
		sb = sb.replace(sb.length()-1, sb.length(), "");
		sb.append("]}");
		
		resp.setContentType("text/json");
		resp.getWriter().println(sb.toString());
	}

	private void doStop(HttpServletRequest req, HttpServletResponse resp, String idJob) { }

	private void doQuery(HttpServletRequest req, HttpServletResponse resp, String queryParameter) throws IOException {
		UpdateQuery query;
		QueryManager queryManager = new QueryManagerFactory().createQueryManager();
		UpdateExecutor updateExecutor = queryManager.createUpdateExecutor();
		
		String idJob;
		
		try {
    		CharStream cs = new ANTLRStringStream(queryParameter);
    		
            UpdateQueryLexer lex = new UpdateQueryLexer(cs);
            CommonTokenStream tokens = new CommonTokenStream(lex);

            UpdateQueryParser g = new UpdateQueryParser(tokens);
            query = g.query();
            
            if (g.failed()) {
            	throw new RecognitionException();
            }
            
            idJob = updateExecutor.execute(query);    
        } 
		catch(IllegalArgumentException e1) {
        	idJob = updateExecutor.createFailedJob(e1.getMessage());			
		}
		catch (RecognitionException e2) {
        	idJob = updateExecutor.createFailedJob(e2.getMessage());
        }
        
		resp.setContentType("text/json");
		resp.getWriter().println("{ \"idJob\": \"" + idJob + "\" }");
	}
}
